<?php

declare(strict_types=1);
/**
 * This file is part of MoChat.
 * @link     https://mo.chat
 * @document https://mochat.wiki
 * @contact  group@mo.chat
 * @license  https://github.com/mochat-cloud/mochat/blob/master/LICENSE
 */
namespace MoChat\App\WorkContact\Logic\FieldPivot;

use Hyperf\Di\Annotation\Inject;
use Hyperf\Utils\Codec\Json;
use MoChat\App\Corp\Utils\WeWorkFactory;
use MoChat\App\WorkContact\Constants\Field\Options;
use MoChat\App\WorkContact\Contract\ContactFieldPivotContract;
use MoChat\App\WorkContact\Contract\WorkContactContract;
use MoChat\App\WorkContact\Contract\WorkContactEmployeeContract;
use MoChat\App\WorkEmployee\Contract\WorkEmployeeContract;
use MoChat\Framework\Constants\ErrorCode;
use MoChat\Framework\Exception\CommonException;
use MoChat\Plugin\ContactTrack\Constants\Event;
use MoChat\Plugin\ContactTrack\Constants\EventName;
use MoChat\Plugin\ContactTrack\Contract\ContactTrackContract;

/**
 * 修改用户画像.
 *
 * Class UpdateLogic
 */
class UpdateLogic
{
    /**
     * @Inject
     * @var WorkContactEmployeeContract
     */
    protected $workContactEmployeeService;

    /**
     * @Inject
     * @var WeWorkFactory
     */
    protected $weWorkFactory;

    /**
     * @Inject
     * @var WorkContactContract
     */
    protected $workContactService;

    /**
     * @Inject
     * @var WorkEmployeeContract
     */
    protected $workEmployeeService;

    /**
     * 用户画像表.
     * @Inject
     * @var ContactFieldPivotContract
     */
    private $contactFieldPivot;

    /**
     * 互动轨迹表.
     * @Inject
     * @var ContactTrackContract
     */
    private $track;

    /**
     * 参数.
     * @var array
     */
    private $params;

    /**
     * @return array
     */
    public function handle(array $params)
    {
        $this->params = $params;

        // 修改用户画像 并记录轨迹
        $this->update();
        // 同步修改remark_mobiles字段
        $this->syncUpdateRemarkMobiles();

        return [];
    }

    /**
     * 修改用户画像 并记录轨迹.
     */
    private function update()
    {
        if (! is_array($this->params['userPortrait'])) {
            $this->params['userPortrait'] = Json::decode($this->params['userPortrait']);
        }
        $userPortrait = $this->params['userPortrait'];
        if (empty($userPortrait)) {
            return;
        }

        $content = '编辑用户画像：';
        $createData = [];
        // 处理数据
        foreach ($userPortrait as $key => &$raw) {
            $value = $raw['value'];
            // 多选
            if ($raw['type'] == Options::CHECKBOX) {
                // 数组转字符串
                if (! empty($raw['value'])) {
                    $value = implode(',', $raw['value']);
                } else {
                    $value = '';
                }
            }

            // 如果没有用户画像 则新增
            $contactFieldPivot = $this->contactFieldPivot->getContactFieldPivotsByOtherId((int) $this->params['contactId'], [$raw['contactFieldId']], ['id','value']);
            if (empty($contactFieldPivot)) {
                // 新增用户画像
                $createData[] = [
                    'contact_id' => $this->params['contactId'],
                    'contact_field_id' => $raw['contactFieldId'],
                    'value' => $value,
                ];
                // 记录轨迹
                if (! empty($value)) {
                    // 轨迹数据
                    $content .= '添加【'.$raw['name'] . '】为'.$value;
                }
            } else {
                // 查询表中用户画像值
                $pivotId = (int) $raw['contactFieldPivotId'] > 0 ? (int) $raw['contactFieldPivotId'] : $contactFieldPivot[0]['id'];
                $res = $this->contactFieldPivot->getContactFieldPivotById($pivotId, ['value']);
                // 记录轨迹
                if (! empty($res) && $res['value'] != $value) {
                    // 轨迹数据
                    $content .= '【'.$raw['name'] .'】'. $contactFieldPivot[0]['value'].'修改成'.$value;
                }
                $updateRes = $this->contactFieldPivot
                    ->updateContactFieldPivotById($pivotId, ['value' => $value]);
                if (! is_int($updateRes)) {
                    throw new CommonException(ErrorCode::SERVER_ERROR, '编辑用户画像失败');
                }
            }
        }

        if ($content != '编辑用户画像：') {
            // 记录轨迹
            $this->recordTrack($content);
        }

        if (! empty($createData)) {
            $createRes = $this->contactFieldPivot->createContactFieldPivots($createData);
            if ($createRes != true) {
                throw new CommonException(ErrorCode::SERVER_ERROR, '添加用户画像失败');
            }
        }
    }

    /**
     * 记录轨迹.
     * @param $content
     */
    private function recordTrack($content)
    {
        $jsonContact = [
            'title' => EventName::INFO,
            'content' => $content,
        ];
        $data = [
            'employee_id' => $this->params['employeeId'],
            'contact_id' => $this->params['contactId'],
            'content' => Json::encode($jsonContact),
            'corp_id' => $this->params['corpId'],
            'event' => Event::USER_PORTRAIT,
        ];

        $res = $this->track->createContactTrack($data);
        if (! is_int($res)) {
            throw new CommonException(ErrorCode::SERVER_ERROR, '记录轨迹失败');
        }
    }

    private function syncUpdateRemarkMobiles()
    {
        // 修改画像-手机号
        if (! is_array($this->params['userPortrait'])) {
            $this->params['userPortrait'] = Json::decode($this->params['userPortrait'], true);
        }
        $userPortrait = $this->params['userPortrait'];
        if (empty($userPortrait)) {
            return;
        }

        // 处理数据
        foreach ($userPortrait as $item) {
            if ($item['name'] == '手机号' && ! empty($item['value'])) {
                $contactEmployee = $this->workContactEmployeeService->getWorkContactEmployeeByOtherId($this->params['employeeId'], $this->params['contactId'], ['id', 'remark_mobiles']);
                if (empty($contactEmployee)) {
                    return;
                }
                $contactEmployeeRemarkMobiles = Json::decode($contactEmployee['remarkMobiles']);
                if (! empty($contactEmployeeRemarkMobiles) && $item['value'] == $contactEmployeeRemarkMobiles[0]) {
                    return;
                }

                if (empty($contactEmployeeRemarkMobiles)) {
                    $remarkMobiles = [$item['value']];
                } else {
                    $contactEmployeeRemarkMobiles[0] = $item['value'];
                    $remarkMobiles = $contactEmployeeRemarkMobiles;
                }
                $this->workContactEmployeeService->updateWorkContactEmployeeById($contactEmployee['id'], ['remark_mobiles' => Json::encode($remarkMobiles)]);
                // 同步到企业微信
                // 员工
                $employee = $this->workEmployeeService->getWorkEmployeeById($this->params['employeeId'], ['wx_user_id']);
                if (empty($employee)) {
                    return;
                }
                // 客户
                $contact = $this->workContactService->getWorkContactById($this->params['contactId'], ['wx_external_userid']);
                if (empty($contact)) {
                    return;
                }
                $data = [
                    'userid' => $employee['wxUserId'],
                    'external_userid' => $contact['wxExternalUserid'],
                    'remark_mobiles' => $remarkMobiles,
                ];
                $weWorkApp = $this->weWorkFactory->getContactApp($this->params['corpId']);
                $res = $weWorkApp->external_contact->remark($data);
            }
        }
    }
}
